Visualizing Networks

In [1]:
%matplotlib notebook

import networkx as nx
import matplotlib.pyplot as plt


G = nx.read_gpickle('major_us_cities')

draw_networkx uses the spring layout by default, which tries to position nodes with as few crossing edges as possible, while keeping edge lengths similar.

In [2]:
plt.figure(figsize=(10,9))
nx.draw_networkx(G)

These are the layouts networkx provides:

In [3]:
[x for x in nx.__dir__() if x.endswith('_layout')]
Out[3]:
['circular_layout',
 'random_layout',
 'shell_layout',
 'spring_layout',
 'spectral_layout',
 'fruchterman_reingold_layout']
In [4]:
# use the random layout positions
plt.figure(figsize=(10,9))
pos = nx.random_layout(G)
nx.draw_networkx(G, pos)
In [5]:
# use the circular layout positions
plt.figure(figsize=(10,9))
pos = nx.circular_layout(G)
nx.draw_networkx(G, pos)

You can use your own layout by passing in a dictionary of node positions. Let's use our distribution network's node attribute of location for the position.

Now the network visualization resembles the geographic United States.

In [6]:
plt.figure(figsize=(10,7))

pos = nx.get_node_attributes(G, 'location')
nx.draw_networkx(G, pos)

Lets make the structure of the network easier to see by removing some information.

In [7]:
plt.figure(figsize=(10,7))

nx.draw_networkx(G, pos, alpha=0.7, with_labels=False, edge_color='.4')

plt.axis('off')
plt.tight_layout();

Let's set the node color based on the degree of the node, the node size based on the population of each node, and set the edge widths to the weights or the costs of each edge.

Now we can quickly see which nodes in our distribution network have high population / high degree.

In [8]:
plt.figure(figsize=(10,7))

node_color = [G.degree(v) for v in G]
node_size = [0.0005*nx.get_node_attributes(G, 'population')[v] for v in G]
edge_width = [0.0015*G[u][v]['weight'] for u,v in G.edges()]

nx.draw_networkx(G, pos, node_size=node_size, 
                 node_color=node_color, alpha=0.7, with_labels=False, 
                 width=edge_width, edge_color='.4', cmap=plt.cm.Blues)

plt.axis('off')
plt.tight_layout();

We can plot edges separately to visually identify the most expensive edges in our network, where the cost is greater than 770.

Using draw_networkx_labels we can add labels to Los Angeles and New York City.

In [9]:
plt.figure(figsize=(10,7))

node_color = [G.degree(v) for v in G]
node_size = [0.0005*nx.get_node_attributes(G, 'population')[v] for v in G]
edge_width = [0.0015*G[u][v]['weight'] for u,v in G.edges()]

nx.draw_networkx(G, pos, node_size=node_size, 
                 node_color=node_color, alpha=0.7, with_labels=False, 
                 width=edge_width, edge_color='.4', cmap=plt.cm.Blues)


greater_than_770 = [x for x in G.edges(data=True) if x[2]['weight']>770]
nx.draw_networkx_edges(G, pos, edgelist=greater_than_770, edge_color='r', alpha=0.4, width=6)

nx.draw_networkx_labels(G, pos, labels={'Los Angeles, CA': 'LA', 'New York, NY': 'NYC'}, font_size=18, font_color='w')

plt.axis('off')
plt.tight_layout();